package myalg.nonblocking;

import java.util.concurrent.atomic.AtomicReference;

/**
 * @author Pavel Belevich
 *         Date: Jul 2, 2012
 *         Time: 4:27:49 PM
 */
public class NonblockingStack<T> {

    private static class Element<T> {

        private T data;
        private Element<T> next;

        private Element(T data, Element<T> next) {
            this.data = data;
            this.next = next;
        }

        public T getData() {
            return data;
        }

        public void setData(T data) {
            this.data = data;
        }

        public Element<T> getNext() {
            return next;
        }

        public void setNext(Element<T> next) {
            this.next = next;
        }

    }

    private AtomicReference<Element<T>> head = new AtomicReference<Element<T>>();

    public NonblockingStack() {
    }

    public void push(T data) {
        Element<T> newElement;
        Element<T> headElement;
        do {
            headElement = head.get();
            newElement = new Element<T>(data, headElement);
        } while (!head.compareAndSet(headElement, newElement));
    }

    public T pop() {
        Element<T> newElement;
        Element<T> headElement;
        do {
            headElement = head.get();
            newElement = headElement.getNext();
        } while (!head.compareAndSet(headElement, newElement));
        return newElement.getData();
    }

    public static void main(String[] args) {
        final NonblockingStack<Integer> stack = new NonblockingStack<Integer>();
        new Thread() {
            @Override
            public void run() {
                
            }
        }.start();
        new Thread() {
            @Override
            public void run() {

            }
        }.start();
    }

}
